#ifndef __STACK_H__
#define __STACK_H__

//define stack return code
#define STACK_OK        0
#define STACK_FULL      -1
#define STACK_EMPTY     -2
#define STACK_FAIL      -3


struct stack {
    void **elements;
    unsigned int size;  // sizeof elements
    int sp;  // -1: null
};

typedef struct stack stack_t;


//interface (operation of stack)

int init(stack_t *, int size); // return STACK_FAIL if malloc error
int push(stack_t *, void *);   //return STACK_FULL if error
// retVaule =  top of stack and return STACK_OK if stack is not empty, 
// otherwise return STACK_EMPTY
int pop(stack_t *, void** retNodeAddress);

// other pop method, returen node address and errorCode
// == STACK_OK if stack is not empty, 
// otherwise return STACK_EMPTY
void *pop2(stack_t *, int *errorCode);

int isFULL(stack_t *);  //return 1 if stack is full
int isEmpty(stack_t *); // return 1 if stack is empty
// return 1 if node is contained in stack, 
// where compareFunc is your compare funtion.
// compareFunc return 0 if key of elementNode == key (integer, float or string)  
int isExist(stack_t *stackPtr, void *key, int (*compareFunc)(void *elementNode, void *key));

#endif